<?php

namespace app\data\controller\api\auth;

use app\data\controller\api\Auth;
use app\data\service\AliMessageService;
use app\data\service\CarService;
use app\data\service\UserAdminService;
use GuzzleHttp\Client;
use think\facade\Cache;
use think\facade\Log;
use WeChat\Contracts\BasicWeChat;

/**
 * 用户资料管理
 * Class Center
 * @package app\data\controller\api\auth
 */
class Center extends Auth
{
    /**
     * 绑定数据表
     * @var string
     */
    private $table = 'DataUser';

    /**
     * 更新用户资料
     * @throws \think\db\exception\DbException
     */
    public function set()
    {
        $data = $this->_vali([
            'headimg.default'       => '',
            'username.default'      => '',
            'nickname.default'      => '',
            'base_age.default'      => '',
            'base_sex.default'      => '',
            'base_birthday.default' => '',
            'password.default' => '',
            'real_name.default' => '',
            'region_province.default' => '',
            'region_city.default' => '',
            'region_area.default' => '',
        ]);
        foreach ($data as $key => $vo) {
            if ($vo === '') {
                unset($data[$key]);
            }

            if ($key == 'password' && $vo !== '') {
                $data['password'] = md5($data['password']);
            }
        }
        if (empty($data)) $this->error('没有修改的数据！');

        if (UserAdminService::instance()->set(['id' => $this->uuid], $data, $this->type, true)) {
            $this->success('更新资料成功！', $this->getUser());
        } else {
            $this->error('更新资料失败！');
        }
    }

    /**
     * 获取用户资料
     */
    public function get()
    {
        $user = $this->getUser();
        if (!empty($user['id_card'])) {
            $user['is_certified'] = 1;
        } else {
            $user['is_certified'] = 0;
        }
        $user['is_band_bank'] = UserAdminService::instance()->isBindBankByUserId($user['id'] ?? 0);
        $user['is_service_provider'] = UserAdminService::instance()->isServiceProvider($user);
        $user['has_car'] = CarService::instance()->hasCar($user['id'] ?? 0);

        $this->success('获取用户资料', $user);
    }

    /**
     * 绑定邀请码
     * @throws \think\db\exception\DbException
     */
    public function bindInviteCode()
    {
        $data = $this->_vali([
            'invite_code.require'       => '邀请码不能为空',
        ]);

        if ($this->user['pid']) {
            $this->error('您已经绑定邀请码了，请勿重复绑定！');
        }

        $user = $this->app->db->name('data_user')->where('deleted', 0)->where('invite_code', $data['invite_code'])->find();
        if (empty($user)) {
            $this->error('查无该邀请码！');
        }

        if ($user['id'] == $this->uuid) {
            $this->error('不能自己绑定自己的邀请码');
        }

        if (UserAdminService::instance()->set(['id' => $this->uuid], ['pid' => $user['id']], $this->type, true)) {
            $this->success('绑定邀请码成功！');
        } else {
            $this->error('绑定邀请码失败！');
        }
    }

    /**
     * 服务商注册
     * @return void
     * @throws \think\admin\Exception
     * @throws \think\db\exception\DbException
     */
    public function registerServiceProvider()
    {
        if ($this->user['service_provider_status'] === 1) {
            $this->error('您已经是服务商了，请勿重复注册');
        }

        if ($this->user['service_provider_status'] === -1) {
            $this->error('服务商注册中');
        }

        $data = $this->_vali([
            'nickname.require'       => '姓名不能为空！',
            'region_province.require'      => '省不能为空！',
            'region_city.require'      => '市不能为空！',
            'region_area.require'      => '区不能为空！',
            'car_monitoring_station_ids.require'   => '检测站信息不能为空！',
        ]);
        $data['service_provider_status'] = -1;

        $this->app->db->name('car_monitoring_station_relation')->where('uuid', $this->uuid)->delete();
        foreach ($data['car_monitoring_station_ids'] as $carMonitoringStationId) {
            $insertData[] = [
                'uuid' => $this->uuid,
                'car_monitoring_station_id' => $carMonitoringStationId,
            ];
        }
        if (!empty($insertData)) {
            $this->app->db->name('car_monitoring_station_relation')->insertAll($insertData);
        }

        if (UserAdminService::instance()->set(['id' => $this->uuid], $data, $this->type, true)) {
            $this->success('申请服务商注册成功！', $this->getUser());
        } else {
            $this->error('申请服务商注册失败！');
        }
    }

    /**
     * 换绑手机
     * @throws \think\db\exception\DbException
     */
    public function changePhone()
    {
        $data = $this->_vali([
            'verify.require'      => '验证码不能为空',
            'phone.mobile'     => '手机号码格式错误！',
            'phone.require'    => '手机号码不能为空！',
            'channel_id.default' => 0,
            'channel_change.default' => 0
        ]);

        if ($data['channel_change']) {
            $channelId = $data['channel_id'];
        } else {
            $channelId = 0;
        }

        if (!AliMessageService::instance()->checkVerifyCode($data['verify'], $data['phone'], 'change_phone')) {
            $this->error('验证码错误，请稍候再试！');
        }

        $this->bindPhone($data['phone'], $this->uuid, $channelId);

        $this->success('换绑手机号成功！');
    }

    /**
     * 授权绑定手机号码
     * @return void
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \WeChat\Exceptions\InvalidResponseException
     * @throws \WeChat\Exceptions\LocalCacheException
     */
    public function phone()
    {
        $data = $this->_vali([
            'code.require'      => 'code不能为空',
            'channel_id.default' => 0,
            'channel_change.default' => 0
        ]);

        $config = [
            'appid'      => sysconf('data.wxapp_appid'),
            'appsecret'  => sysconf('data.wxapp_appkey'),
            'cache_path' => $this->app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . 'wechat',
        ];

        $url = 'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=' . BasicWeChat::instance($config)->getAccessToken();

        $client = new Client();
        $response = $client->post($url, ['body' => json_encode(['code' => $data['code']]), 'verify' => false]);
        $response = $response->getBody();
        $response = json_decode($response, true);
        $phone = $response['phone_info']['phoneNumber'] ?? '';
        if (empty($phone)) {
            $this->error('手机号码授权失败！', $response);
        }

        if ($data['channel_change']) {
            $channelId = $data['channel_id'];
        } else {
            $channelId = 0;
        }

        $this->bindPhone($phone, $this->uuid, $channelId);

        $this->success('绑定手机号成功！');
    }

    /**
     * 解绑成功
     * @param $phone
     * @param $uuid
     * @return bool
     */
    public function unbindPhone()
    {
        $this->app->db->name('data_user')->where('id', $this->uuid)->update(['phone' => '']);
        $cacheKey = config('cacheKey.uid2user') . $this->uuid;
        Cache::delete($cacheKey);
        $this->success('解绑成功');
    }

    /**
     * 绑定手机号码
     * @param $phone
     * @param $uuid
     * @return bool
     */
    public function bindPhone($phone, $uuid, $channelId)
    {
        if ($this->app->db->name('data_user')->where('openid1', '<>', '')->where(['phone' => $phone])->where('deleted', 0)->where('id','<>', $uuid)->count() > 0) {
            $this->error('号码已经被绑定过了，请更换其他号码！');
        }

        // 写入数据
        $this->app->db->transaction(function () use ($phone, $uuid, $channelId) {
            if ($oldPhoneUser = $this->app->db->name('data_user')->where('openid1', '')->where(['phone' => $phone])->where('deleted', 0)->where('id','<>', $uuid)->find()) {
                $this->app->db->name('data_user')->where('id', $oldPhoneUser['id'])->delete();
                $updateData['service_provider_status'] = $oldPhoneUser['service_provider_status'];
            }

            $user = $this->app->db->name('data_user')->where('id', $uuid)->find();
            if (!empty($channelId) && empty($user['channel_id'])) {
                $updateData['channel_id'] = $channelId;
            }

            $updateData['phone'] = $phone;
            $this->app->db->name('data_user')->where('id', $uuid)->update($updateData);

            $cacheKey = config('cacheKey.uid2user') . $uuid;
            Cache::delete($cacheKey);
        });

        return true;
    }

    /**
     * 身份证二要素识别
     * @return void
     */
    public function realNameAuthentication()
    {
        $data = $this->_vali([
            'id_card.require' => '身份证号码不能为空',
            'real_name.require' => '姓名不能为空',
        ]);

        $appCode = '5b78fb3b6eca44b39e6b71569b79ef0a';
        $url = 'https://zid.market.alicloudapi.com/idcheck/Post';

        $client = new Client();
        $response = $client->post($url, [
            'form_params' => ([
                'cardNo' => $data['id_card'],
                'realName' => ($data['real_name'])
            ]),
            'verify' => false,
            'headers' => [
                "Authorization" => 'APPCODE ' . $appCode,
                "Content-Type" => 'application/x-www-form-urlencoded',
            ]
        ]);
        $response = $response->getBody();
        $response = json_decode($response, true);

        if (isset($response['error_code']) && $response['error_code'] === 0 && ($response['result']['isok'] ?? false)) {

            $this->app->db->name('data_user')->where('id', $this->uuid)->update($data);

            $cacheKey = config('cacheKey.uid2user') . $this->uuid;
            Cache::delete($cacheKey);

            $this->success('身份证实名校验通过！');
        }

        $this->error('身份证实名校验失败！', $response);
    }

    /**
     * 获取好友列表
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function son()
    {
        $user = $this->_query('data_user')->where(['status' => 1, 'deleted' => 0, 'pid' => $this->uuid]);
        $user = $user->field('id,nickname,headimg,create_at')->order('id desc')->page(true, false, false, input('limit', 10));

        foreach ($user['list'] as &$item) {
            $item = UserAdminService::instance()->formatUserField($item, false);
        }

        $this->success('获取好友列表', $user);
    }
}